home *** CD-ROM | disk | FTP | other *** search
/ CU Amiga Super CD-ROM 15 / CU Amiga Magazine's Super CD-ROM 15 (1997)(EMAP Images)(GB)[!][issue 1997-10].iso / CUCD / Graphics / Ghostscript / source / gs_pdfwr.ps < prev    next >
Encoding:
Text File  |  1997-05-31  |  10.6 KB  |  352 lines

  1. %    Copyright (C) 1996, 1997 Aladdin Enterprises.  All rights reserved.
  2. %
  3. % This file is part of Aladdin Ghostscript.
  4. % Aladdin Ghostscript is distributed with NO WARRANTY OF ANY KIND.  No author
  5. % or distributor accepts any responsibility for the consequences of using it,
  6. % or for whether it serves any particular purpose or works at all, unless he
  7. % or she says so in writing.  Refer to the Aladdin Ghostscript Free Public
  8. % License (the "License") for full details.
  9. % Every copy of Aladdin Ghostscript must include a copy of the License,
  10. % normally in a plain ASCII text file named PUBLIC.  The License grants you
  11. % the right to copy, modify and redistribute Aladdin Ghostscript, but only
  12. % under certain conditions described in the License.  Among other things, the
  13. % License requires that the copyright notice and this notice be preserved on
  14. % all copies.
  15.  
  16. % gs_pdfwr.ps
  17. % PDF writer additions to systemdict.
  18.  
  19. % This file should be included iff the pdfwrite "device" is included
  20. % in the executable.
  21.  
  22. % Redefine pdfmark to pass the data to the driver.
  23. % We use a pseudo-parameter named /pdfmark whose value is an array:
  24. %    key1 value1 ... CTM /type
  25. /.pdf===dict mark
  26.   /arraytype
  27.    { dup xcheck { ({) (}) } { ([) (]) } ifelse
  28.         % Stack: file obj left right
  29.       4 1 roll 2 index exch writestring () exch
  30.        { exch 2 index exch writestring
  31.      1 index exch pdfmark===only ( )
  32.        }
  33.       forall pop exch writestring
  34.    } bind
  35.   /packedarraytype 1 index
  36.   /dicttype
  37.    { 1 index (<<\n) writestring
  38.       { 2 index 3 -1 roll pdfmark===only 1 index ( ) writestring
  39.     1 index exch pdfmark===only dup (\n) writestring
  40.       }
  41.      forall (>>) writestring
  42.    } bind
  43. .dicttomark readonly def
  44. /pdfmark===only        % <file> <obj> pdfmark===only -
  45.  { .pdf===dict 1 index type .knownget { exec } { write==only } ifelse
  46.  } bind def
  47. /.pdfcvs        % <obj> .pdfcvs <string>
  48.  {        % We can't handle long values yet.
  49.    =string /NullEncode filter dup 2 index pdfmark===only
  50.    dup (\n\000) writestring closefile pop
  51.    =string (\n\000) search
  52.     { dup length string copy exch pop exch pop }
  53.     {        % The converted representation didn't fit.  Punt.
  54.       pop (???)
  55.     }
  56.    ifelse
  57.  } bind def
  58. /.pdfputparams        % <paramarray> <paramname> .pdfputparams <result...>
  59.  { currentdevice null false mark 6 -2 roll exch
  60.         % Don't allow the page device to get cleared....
  61.      {.putdeviceparams} 0 get .currentpagedevice pop {.setpagedevice} 0 get
  62.    3 array astore cvx exec
  63.  } bind def
  64. /pdfmark        % -mark- <key> <value> ... <markname> pdfmark -
  65.  { counttomark 1 add copy
  66.    matrix currentmatrix .pdfcvs exch ]
  67.    1 2 2 index length 3 sub { 2 copy 2 copy get .pdfcvs put pop } for
  68.    /pdfmark .pdfputparams
  69.    type /booleantype ne { cleartomark } if cleartomark
  70.  } odef
  71. userdict /pdfmark .undef
  72.  
  73. % Define setdistillerparams / currentdistillerparams.
  74. % Distiller parameters are currently treated as device parameters.
  75. /.distillerparamkeys mark
  76.         % General parameters
  77.   /ASCII85EncodePages { }
  78.   /AutoRotatePages { }
  79.   /CompatibilityLevel { }
  80.   /CompressPages { }
  81.   /CoreDistVersion { }
  82.   /DoThumbnails { }
  83.   /ImageMemory { }
  84.   /LZWEncodePages { }
  85.   /PreserveHalftoneInfo { }
  86.   /PreserveOPIComments { }
  87.   /PreserveOverprintSettings { }
  88.   /TransferFunctionInfo { }
  89.   /UCRandBGInfo { }
  90.   /UseFlateCompression { }
  91.         % Color sampled image parameters
  92.   /ColorACSDict { }
  93.   /AntiAliasColorImages { }
  94.   /AutoFilterColorImages { }
  95.   /ColorImageDepth { }
  96.   /ColorImageDict { }
  97.   /DownsampleColorImages { }
  98.   /ColorImageDownsampleType { }
  99.   /EncodeColorImages { }
  100.   /ColorImageFilter { }
  101.   /ColorImageResolution { }
  102.   /ColorConversionStrategy { }
  103.   /ConvertCMYKImagesToRGB { }
  104.   /ConvertImagesToIndexed { }
  105.         % Grayscale sampled image parameters
  106.   /GrayACSDict { }
  107.   /AntiAliasGrayImages { }
  108.   /AutoFilterGrayImages { }
  109.   /GrayImageDepth { }
  110.   /GrayImageDict { }
  111.   /DownsampleGrayImages { }
  112.   /GrayImageDownsampleType { }
  113.   /EncodeGrayImages { }
  114.   /GrayImageFilter { }
  115.   /GrayImageResolution { }
  116.         % Monochrome sampled image parameters
  117.   /AntiAliasMonoImages { }
  118.   /MonoImageDepth { }
  119.   /MonoImageDict { }
  120.   /DownsampleMonoImages { }
  121.   /MonoImageDownsampleType { }
  122.   /EncodeMonoImages { }
  123.   /MonoImageFilter { }
  124.   /MonoImageResolution { }
  125.         % Font embedding parameters
  126.   /AlwaysEmbed
  127.    { dup length 0 gt
  128.       { dup 0 get false eq
  129.          { dup length 1 sub 1 exch getinterval exch pop /~AlwaysEmbed exch
  130.          } if
  131.       } if
  132.    }
  133.   /NeverEmbed
  134.    { dup length 0 gt
  135.       { dup 0 get false eq
  136.          { dup length 1 sub 1 exch getinterval exch pop /~NeverEmbed exch
  137.          } if
  138.       } if
  139.    }
  140.   /EmbedAllFonts { }
  141.   /SubsetFonts { }
  142.   /MaxSubsetPct { }
  143. .dicttomark readonly def
  144. /.distillerdevice
  145.  { currentdevice .devicename /pdfwrite eq
  146.     { currentdevice }
  147.     { /pdfwrite finddevice }
  148.    ifelse
  149.  } bind def
  150. /setdistillerparams        % <dict> setdistillerparams -
  151.  { .distillerdevice null false mark 4 index
  152.     { //.distillerparamkeys 2 index .knownget { exec } { pop pop } ifelse }
  153.    forall .putdeviceparams
  154.    type /booleantype eq { pop } { cleartomark pop pop pop } ifelse pop
  155.  } odef
  156. /currentdistillerparams        % - currentdistillerparams <dict>
  157.  { .distillerdevice //.distillerparamkeys .getdeviceparams .dicttomark
  158.  } odef
  159.  
  160. % Patch the 'show' operators to pass the data to the device.
  161. % We use a pseudo-parameter named /show whose value is a dictionary:
  162. %    /String (str)
  163. %    /Values [cx cy char ax ay px py]
  164. %    /Matrix [xx xy yx yy tx ty]
  165. %    /FontName /fontname
  166. %    /Encoding [e0 .. e255]
  167. %    /BaseEncoding [e0 ... e255]
  168. % We also fill an empty path in order to get the clipping region and
  169. % current color set properly.  THIS IS A BIG HACK.
  170. /.pdfknownfonts mark
  171.   /Courier null
  172.   /Courier-Bold null
  173.   /Courier-Oblique null
  174.   /Courier-BoldOblique null
  175.   /Helvetica null
  176.   /Helvetica-Bold null
  177.   /Helvetica-Oblique null
  178.   /Helvetica-BoldOblique null
  179.   /Symbol null
  180.   /Times-Roman null
  181.   /Times-Bold null
  182.   /Times-Italic null
  183.   /Times-BoldItalic null
  184.   /ZapfDingbats null
  185. .dicttomark readonly def
  186. .currentglobal false .setglobal
  187. /.pdfknownids 50 dict def
  188. .setglobal
  189. /.findorigfont {    % <font> .findorigfont <origfont>
  190.             % Check for a known font with the same name,
  191.             % or one of the 14 known names,
  192.             % and the same UniqueID.
  193.   dup /UniqueID .knownget {
  194.     .pdfknownids 1 index .knownget {
  195.       exch pop dup null ne { true } { pop false } ifelse
  196.     } {            % We haven't looked up the UniqueID yet.
  197.             % Register the UniqueIDs of all fonts.
  198.       .FontDirectory {
  199.     exch pop dup /UniqueID .knownget {
  200.             % Stack: font uniqueid somefont somefontid
  201.       exch .pdfknownids 3 1 roll put
  202.     } {
  203.       pop
  204.     } ifelse
  205.       } forall
  206.             % Register the UniqueIDs of the 14 built-in fonts,
  207.             % to make sure they override any other fonts
  208.             % with the same UniqueIDs.
  209.       .pdfknownfonts {
  210.     pop .FontDirectory 1 index .knownget {
  211.             % Stack: font uniqueid knownname knownfont
  212.       dup /UniqueID get exch .pdfknownids 3 1 roll put
  213.     } if pop
  214.       } forall
  215.             % Now see if the UniqueID is known.
  216.       .pdfknownids 1 index .knownget {
  217.     exch pop true
  218.       } {            % Record the UniqueID as not registered.
  219.     .pdfknownids exch null put false
  220.       } ifelse
  221.     } ifelse
  222.   } {            % This font has no UniqueID.
  223.     false
  224.   } ifelse
  225.             % Stack: font knownfont -true- | font -false-
  226.   {
  227.     exch pop
  228.   } {
  229.     { dup /OrigFont .knownget not { exit } if exch pop } loop
  230.   } ifelse
  231. } .bind def
  232. /setvmthreshold where { pop 1000000 setvmthreshold } if
  233. /.pdfdoshow        % <string> <cxd> <cyd> <char> <axd> <ayd> .pdfdoshow
  234.             %   <bool>
  235.  { mark /String 8 2 roll
  236. %vmstatus pop =only pop (, ) print
  237.    currentpoint transform 7 array astore /Values exch
  238.    currentfont .findorigfont
  239.         % Pass the original font name.
  240.    dup /FontName get
  241.    /FontName exch 3 -1 roll
  242.         % Concatenate the "quotient" of the current FontMatrix
  243.         % and the FontMatrix of the original font.
  244.         % Be sure to include any translation.
  245.    /Matrix
  246.      exch /FontMatrix get matrix invertmatrix
  247.      currentfont /FontMatrix get 1 index concatmatrix
  248.      matrix currentmatrix dup 4 0 put dup 5 0 put dup concatmatrix
  249.    /Encoding currentfont /Encoding .knownget not { [] } if
  250.     % Make a reasonable guess at the base encoding.
  251.    /BaseEncoding StandardEncoding
  252. %vmstatus pop =only pop (, ) print
  253.    .dicttomark
  254.         % Set the clipping region and color in the output.
  255.         % This is another hack!
  256.    gsave newpath fill grestore
  257. %vmstatus pop =only pop (, ) print
  258.    /show .pdfputparams
  259. %vmstatus pop =only pop () = flush
  260.    dup type /booleantype eq
  261.     { pop pop true }
  262.     { dup /undefined eq
  263.        { cleartomark pop pop pop false }
  264.        { dup mark eq { /unknown /rangecheck } if
  265.      counttomark 4 add 1 roll cleartomark pop pop pop
  266.      /.pdfshow cvx exch signalerror
  267.        }
  268.       ifelse
  269.     }
  270.    ifelse
  271.  } .bind def
  272. /.pdfexecshow        % <proc> .pdfexecshow -
  273.  { matrix currentmatrix gsave nulldevice setmatrix
  274.    exec currentpoint grestore moveto
  275.  } .bind def
  276. /.pdfwrite?        % - .pdfwrite? <bool>
  277.  { currentdevice .devicename /pdfwrite eq
  278.    currentfont /FontType get 1 eq and
  279.  } .bind def
  280. % .pdfshow isn't an operator per se, but it still needs to be careful with
  281. % the stack so that the operators will have stack protection.
  282. /.pdfshow        % <string> <cx> <cy> <char> <ax> <ay> <showproc>
  283.             %   .pdfshow -
  284.  { 7 1 roll .pdfwrite?
  285.     { .pdfdoshow }
  286.     { 6 { pop } repeat false }
  287.    ifelse
  288.     { .pdfexecshow }
  289.     { exec }
  290.    ifelse
  291.  } .bind def
  292. /show
  293.  { dup 0 0 32 0 0 { show } .pdfshow
  294.  } .bind odef
  295. /ashow
  296.  { dup 0 0 32 6 index 6 index { ashow } .pdfshow
  297.  } .bind odef
  298. /widthshow
  299.  { 4 copy 4 -2 roll 4 -1 roll 0 0 { widthshow } .pdfshow
  300.  } .bind odef
  301. /awidthshow
  302.  { 6 copy 6 -2 roll 6 -3 roll { awidthshow } .pdfshow
  303.  } .bind odef
  304. /glyphshow where { pop } { (%END) .skipeof } ifelse
  305. /glyphshow
  306.  { .pdfwrite?
  307.     { currentfont /Encoding .knownget not { {} } if
  308.       0 1 2 index length 1 sub
  309.        {        % Stack: glyph encoding index
  310.      2 copy get 3 index eq { exch pop exch pop null exit } if pop
  311.        }
  312.       for null eq
  313.        { (X) dup 0 3 index put show pop }
  314.        { glyphshow }
  315.       ifelse
  316.     }
  317.     { glyphshow
  318.     }
  319.    ifelse
  320.  } .bind odef
  321. %END
  322. /.kshow1 {    % <index> <proc> <string> .kshow1
  323.   (X) dup 0 3 index 6 index get put show
  324.   2 index 1 index length 1 sub lt {
  325.     dup 3 index get exch 4 -1 roll 1 add get
  326.     3 -1 roll exec
  327.   } {
  328.     pop pop pop
  329.   } ifelse
  330. } .bind def
  331. /kshow {
  332.   .pdfwrite? {
  333.         % Construct a closure, and work character by character.
  334.     0 1 2 index length 1 sub 5 -2 roll
  335.     //.kshow1 /exec cvx 4 packedarray cvx for
  336.   } {
  337.     kshow
  338.   } ifelse
  339. } .bind odef
  340. % The remaining operators aren't implemented correctly.
  341. /xshow where {
  342.  pop /xshow { .pdfwrite? { 1 index show pop pop } { xshow } ifelse } .bind odef
  343. } if
  344. /yshow where {
  345.  pop /yshow { .pdfwrite? { 1 index show pop pop } { yshow } ifelse } .bind odef
  346. } if
  347. /xyshow where {
  348.  pop /xyshow { .pdfwrite? { 1 index show pop pop } { xyshow } ifelse } .bind odef
  349. } if
  350.